package com.bsj.sipgateway.web.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.excel.EasyExcelFactory;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.bsj.power.common.config.exception.ApiException;
import com.bsj.power.common.config.global.JsonResult;
import com.bsj.power.common.config.global.JsonResultEnum;
import com.bsj.power.common.constant.AlarmEnum;
import com.bsj.power.common.constant.NumericalConstants;
import com.bsj.power.common.def.dto.AlarmCombinationDTO;
import com.bsj.power.common.def.dto.PageDTO;
import com.bsj.power.common.def.dto.alarmReport.AlarmHandleDTO;
import com.bsj.power.common.def.entity.AlarmCombination;
import com.bsj.power.common.def.entity.ai.AiAlarm;
import com.bsj.power.common.def.entity.alarmReport.AlarmReport;
import com.bsj.power.common.def.entity.gb28181.Device;
import com.bsj.power.common.def.vo.AlarmCombinationVO;
import com.bsj.power.common.def.vo.pls.excel.AiAlarmReportExcelVO;
import com.bsj.power.common.def.vo.web.system.ai.AnnexStatVO;
import com.bsj.power.common.util.DateUtils;
import com.bsj.power.common.util.StringUtils;
import com.bsj.sipgateway.web.service.IAlarmService;
import com.bsj.sipgateway.web.service.IDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author zhaoyang
 * @Date 2024/8/8 19:13
 * @menu ai报警
 */
@Slf4j
@RestController
@RequestMapping("/ai/alarm")
public class AiAlarmController {

    @Autowired
    @Qualifier("alarmServiceImpl")
    private IAlarmService alarmService;

    @Autowired
    @Qualifier("deviceServiceImpl")
    private IDeviceService iDeviceService;


    /**
     * 分页获取AI报警附件列表
     *
     * @param dto        页码开始结束时间
     * @param alarmCode  报警对应的编码
     * @param sceneId    场景id
     * @param deviceName 摄像头国标id（20位）sceneId和deviceName只传一个
     * @param sortType   1升序 2逆序
     * @param alarmLevel 报警级别 0普通报警1一级报警2二级报警
     * @return
     */
    @SaIgnore
    @GetMapping("/doAiAlarmPageList")
    public JsonResult doAiAnnexPageList(PageDTO dto, Integer alarmCode, Integer sceneId, String deviceName, Integer sortType, Integer alarmLevel) {
        if (sortType == null) {
            sortType = 2;
        } else if (sortType != 1 && sortType != 2) { 
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }
        IPage<AlarmReport> page = alarmService.pageList(dto, alarmCode, sceneId, deviceName, sortType, alarmLevel);
        List<AlarmReport> records = page.getRecords();
        long total = page.getTotal();
        JsonResult jsonResult = new JsonResult();
        if (CollectionUtils.isEmpty(records) || total == NumericalConstants.ZERO) {
            return JsonResult.success(new ArrayList<>(), total);
        }
        List<String> deviceIds = records.stream().map(AlarmReport::getDeviceName).distinct().collect(Collectors.toList());
        List<Device> devices = iDeviceService.selectByDeviceIds(deviceIds);
        Map<String, List<Device>> collect = devices.stream().collect(Collectors.groupingBy(Device::getDeviceId));

        Map<String, Device> collect1 = devices.stream().collect(Collectors.toMap(Device::getDeviceId, Function.identity(), (v1, v2) -> v1));

        List<AiAlarm> alarmList = new ArrayList<>();
        for (AlarmReport record : records) {
            AiAlarm aiAlarm = new AiAlarm();
            aiAlarm.setAlarmHandleTime(record.getAlarmHandleTime());
            aiAlarm.setHandleState(record.getHandleState());
            aiAlarm.setHandleWay(record.getHandleWay());
            aiAlarm.setEventDescription(record.getEventDescription());
            aiAlarm.setResponseMeasures(record.getResponseMeasures());
            aiAlarm.setRemark(record.getRemark());
            aiAlarm.setDeviceId(record.getDeviceName());
            aiAlarm.setAlarmType(record.getAlarmType());
            aiAlarm.setFilePath(record.getFilePath());
            aiAlarm.setNickName(collect1.get(record.getDeviceName()).getNickName());
            aiAlarm.setAiId(record.getAlarmId());
            aiAlarm.setDid(collect.get(record.getDeviceName()).get(0).getId());
            aiAlarm.setAlarmName(AlarmEnum.getNameByCode(record.getAlarmType()));
            if (record.getFilePath() != null) {
                if (record.getFilePath().contains("mp4")) {
                    aiAlarm.setAiType("2");
                } else if (record.getFilePath().contains("jpg")) {
                    aiAlarm.setAiType("1");
                }
            }
            aiAlarm.setCreateTime(record.getBeginTime());
            aiAlarm.setEndTime(new Date(record.getBeginTime().getTime() + 15000));
            aiAlarm.setLevel("1");
            aiAlarm.setAlarmLevel(record.getAlertLevel());
            if (record.getAlertLevel() == 0) {
                aiAlarm.setAlarmLevelName("普通报警");
            } else if (record.getAlertLevel() == 1) {
                aiAlarm.setAlarmLevelName("一级报警");
            } else if (record.getAlertLevel() == 2) {
                aiAlarm.setAlarmLevelName("二级报警");
            }
            alarmList.add(aiAlarm);
        }
        jsonResult.setCode(JsonResultEnum.SUCCESS.getCode());
        jsonResult.setMsg(JsonResultEnum.SUCCESS.getMsg());
        jsonResult.setTotal(total);
        jsonResult.setData(alarmList);
        return jsonResult;
    }


    /**
     * 附件数据分析统计
     *
     * @param startTime
     * @param endTime
     * @return
     */
    @GetMapping("/doAnalysisAiAnnex")
    public JsonResult<AnnexStatVO> doAnalysisAiAnnex(String startTime, String endTime) {
        return JsonResult.success(alarmService.analysisAiAnnex(startTime, endTime));
    }

    /**
     * 导出AI报警附件信息详情
     *
     * @param response
     * @param dto
     * @param alarmCode
     * @param sceneId
     * @param deviceName
     * @param sortType
     * @throws IOException
     */
    @SaIgnore
    @GetMapping("/exportDetail")
    public void exportDetail(HttpServletResponse response, PageDTO dto, Integer alarmCode, Integer sceneId
            , String deviceName, Integer sortType, Integer alarmLevel) throws IOException {
        List<AlarmReport> records = alarmService.selectList(dto, alarmCode, sceneId, deviceName, sortType, alarmLevel);
        if (CollectionUtils.isEmpty(records)) {
            return;
        }
        List<String> deviceIds = records.stream().map(AlarmReport::getDeviceName).distinct().collect(Collectors.toList());
        List<Device> devices = iDeviceService.selectByDeviceIds(deviceIds);
        Map<String, List<Device>> collect = devices.stream().collect(Collectors.groupingBy(Device::getDeviceId));

        Map<String, Device> collect1 = devices.stream().collect(Collectors.toMap(Device::getDeviceId, Function.identity(), (v1, v2) -> v1));

        List<AiAlarm> alarmList = new ArrayList<>();
        for (AlarmReport record : records) {
            AiAlarm aiAlarm = new AiAlarm();
            aiAlarm.setAlarmHandleTime(record.getAlarmHandleTime());
            aiAlarm.setHandleState(record.getHandleState());
            aiAlarm.setHandleWay(record.getHandleWay());
            aiAlarm.setEventDescription(record.getEventDescription());
            aiAlarm.setResponseMeasures(record.getResponseMeasures());
            aiAlarm.setRemark(record.getRemark());
            aiAlarm.setDeviceId(record.getDeviceName());
            aiAlarm.setAlarmType(record.getAlarmType());
            if (!StringUtils.isEmpty(record.getFilePath())) {
                aiAlarm.setFilePath(record.getFilePath());
            } else {
                aiAlarm.setFilePath("无");
            }
            aiAlarm.setNickName(collect1.get(record.getDeviceName()).getNickName());
            aiAlarm.setAiId(record.getAlarmId());
            aiAlarm.setDid(collect.get(record.getDeviceName()).get(0).getId());
            aiAlarm.setAlarmName(AlarmEnum.getNameByCode(record.getAlarmType()));
            if (!StringUtils.isEmpty(record.getFilePath())) {
                if (record.getFilePath().contains("mp4")) {
                    aiAlarm.setAiType("2");
                } else if (record.getFilePath().contains("jpg")) {
                    aiAlarm.setAiType("1");
                }
            } else {
                aiAlarm.setAiType("无");
            }
            aiAlarm.setAlarmLevel(record.getAlertLevel());
            if (record.getAlertLevel() == 0) {
                aiAlarm.setAlarmLevelName("普通报警");
            } else if (record.getAlertLevel() == 1) {
                aiAlarm.setAlarmLevelName("一级报警");
            } else if (record.getAlertLevel() == 2) {
                aiAlarm.setAlarmLevelName("二级报警");
            }
            aiAlarm.setCreateTime(record.getBeginTime());
            aiAlarm.setEndTime(new Date(record.getBeginTime().getTime() + 15000));
            aiAlarm.setLevel("1");
            alarmList.add(aiAlarm);
        }

        List<AiAlarmReportExcelVO> aiAlarmReportExcelVOS = new ArrayList<>();
        for (int i = 0; i < alarmList.size(); i++) {
            AiAlarm aiAlarm = alarmList.get(i);
            AiAlarmReportExcelVO vo = new AiAlarmReportExcelVO();
            vo.setSerialNum(i + 1);
            vo.setAlarmName(aiAlarm.getAlarmName());
            vo.setNickName(aiAlarm.getNickName());
            vo.setAlarmLevelName(aiAlarm.getAlarmLevelName());
            String aiType = aiAlarm.getAiType();
            if ("1".equals(aiType)) {
                vo.setAiType("图片");
            } else if ("2".equals(aiType)) {
                vo.setAiType("视频");
            } else {
                vo.setAiType("无");
            }
            vo.setMediaUrl(aiAlarm.getFilePath());
            Integer handleState = aiAlarm.getHandleState();
            if (handleState == null) {
                vo.setHandleStateStr("未处理");
            } else {
                if (handleState == 1) {
                    vo.setHandleStateStr("未处理");
                } else if (handleState == 2) {
                    vo.setHandleStateStr("已处理");
                }
            }
            Integer handleWay = aiAlarm.getHandleWay();
            if (handleWay == null) {
                vo.setHandleWayStr("--");
            } else {
                if (handleWay == 1) {
                    vo.setHandleWayStr("语音通报提示");
                } else if (handleWay == 2) {
                    vo.setHandleWayStr("人工现场处理");
                } else if (handleWay == 3) {
                    vo.setHandleWayStr("其他");
                }
            }
            vo.setEventDescription(aiAlarm.getEventDescription());
            vo.setResponseMeasures(aiAlarm.getResponseMeasures());
            vo.setAlarmHandleTimeStr(DateUtils.dateToStr(aiAlarm.getAlarmHandleTime()));
            vo.setCreateTime(DateUtils.dateToStr(aiAlarm.getCreateTime()));

            aiAlarmReportExcelVOS.add(vo);
        }

        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        //编码 防止中文乱码
        String fileName = URLEncoder.encode("AI报警附件信息" + DateUtils.dateToStr(DateUtils.TIME_STANDARD_FORMAT2, new Date()), "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        EasyExcelFactory.write(response.getOutputStream(), AiAlarmReportExcelVO.class).sheet("AI报警附件信息")
                .doWrite(aiAlarmReportExcelVOS);
    }


    /**
     * 新增报警组合
     *
     * @param alarmCombinationDTO
     * @return
     */
    @PostMapping("/alarmComAdd")
    public JsonResult alarmComAdd(@RequestBody AlarmCombinationDTO alarmCombinationDTO) {
        AlarmCombination alarmCombination = new AlarmCombination();
        BeanUtils.copyProperties(alarmCombinationDTO, alarmCombination);
        alarmService.alarmComAdd(alarmCombination);
        return JsonResult.success();
    }

    /**
     * 修改报警组合
     *
     * @param alarmCombinationDTO
     * @return
     */
    @PostMapping("/alarmComUpdate")
    public JsonResult alarmComUpdate(@RequestBody AlarmCombinationDTO alarmCombinationDTO) {
        AlarmCombination alarmCombination = new AlarmCombination();
        BeanUtils.copyProperties(alarmCombinationDTO, alarmCombination);
        alarmService.alarmComUpdate(alarmCombination);
        return JsonResult.success();
    }

    /**
     * 删除报警组合
     *
     * @param id
     * @return
     */
    @GetMapping("/alarmComDelete")
    public JsonResult alarmComDelete(@RequestParam Integer id) {
        alarmService.alarmComDelete(id);
        return JsonResult.success();
    }

    /**
     * 报警组合分页+名称模糊搜索
     *
     * @param pageNumber
     * @param pageSize
     * @param comName
     * @return
     */
    @GetMapping("/listAlarmCom")
    public JsonResult<List<AlarmCombinationVO>> listAlarmCom(@RequestParam Integer pageNumber
            , @RequestParam Integer pageSize, @RequestParam(required = false) String comName) {
        return alarmService.listAlarmCom(pageNumber, pageSize, comName);
    }


    /**
     * 处理报警
     *
     * @param alarmHandleDTO
     * @return com.bsj.power.common.config.global.JsonResult
     * @author ljx
     * @time 2024/5/23 16:02
     */
    @PostMapping("/handleAlarm")
    public JsonResult handleAlarm(@RequestBody @Validated AlarmHandleDTO alarmHandleDTO) {
        return alarmService.handleAlarm(alarmHandleDTO);
    }

}
